package com.meta.shiro;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.meta.auth.PemiFiter;
import com.meta.auth.RolesFilter;
import com.meta.auth.ShiroCommonConfiguration;
import com.meta.auth.ShiroRedisCacheManager;
import com.meta.auth.ShiroRedisSessionDAO;
import javax.servlet.Filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Map;

/**
 *
 */
@Configuration
public class FdShiroConfiguration extends ShiroCommonConfiguration {

    @Autowired
    private ShiroRedisSessionDAO sessionDAO;

    /**
     * securityManager
     *
     * @return
     */
    @Bean("securityManager")
    public SecurityManager securityManager(ShiroRedisCacheManager cacheManager, MyCommonRealm realm) {

        // 2h 7200000L
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager() {

            @Override
            protected Serializable getSessionId(ServletRequest request, ServletResponse response) {

                HttpServletRequest req = (HttpServletRequest) request;
                String jsessionid = req.getHeader("token");
                if (null == jsessionid) {
                    jsessionid = req.getParameter("token");
                }

                return (null != jsessionid ? jsessionid : super.getSessionId(request, response));
            }
        };
        sessionManager.setSessionDAO(this.sessionDAO);
        sessionManager.setGlobalSessionTimeout(7200000L);

        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setSessionManager(sessionManager);
        manager.setCacheManager(cacheManager);
        manager.setRealm(realm);
        ThreadContext.bind(manager);
        return manager;
    }

    @Bean("shiroFilter")
    @ConfigurationProperties("shiro")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager manager) {

        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setLoginUrl("/login");
        bean.setSecurityManager(manager);
        /* 自定义filter注册 */
        Map<String, Filter> filters = bean.getFilters();
        filters.put("authc", new PemiFiter());
        filters.put("roles", new RolesFilter());
        return bean;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator app = new DefaultAdvisorAutoProxyCreator();
        app.setProxyTargetClass(true);
        return app;
    }

}
